home *** CD-ROM | disk | FTP | other *** search
/ QRZ! Ham Radio 8 / QRZ Ham Radio Callsign Database - Volume 8.iso / pc / files / t_unix / j109lxa4.tar / nr4timer.c < prev    next >
C/C++ Source or Header  |  1994-06-04  |  4KB  |  187 lines

  1. /* net/rom level 4 (transport) protocol timer management.
  2.  * Copyright 1989 by Daniel M. Frank, W9NK.  Permission granted for
  3.  * non-commercial distribution only.
  4.  */
  5.  
  6. #include <stdio.h>
  7. #include "global.h"
  8. #include "mbuf.h"
  9. #include "timer.h"
  10. #include "ax25.h"
  11. #include "lapb.h"
  12. #include "netrom.h"
  13. #include "nr4.h"
  14. #include <ctype.h>
  15.  
  16. #undef NR4DEBUG
  17.  
  18. unsigned Nr_timertype = 0;        /* default to binary exponential */
  19.  
  20. /* The ACK timer has expired without any data becoming available.
  21.  * Go ahead and send an ACK.
  22.  */
  23.  
  24. void
  25. nr4ackit(p)
  26. void *p ;
  27. {
  28.     struct nr4cb *cb  = (struct nr4cb *)p ;
  29.     struct nr4hdr rhdr ;
  30.  
  31. #ifdef NR4DEBUG
  32.     printf("ACKIT called.\n") ;
  33. #endif
  34.  
  35.     stop_timer(&cb->tack);  /* fixed N1BEE 920811 */
  36.     if (cb->qfull)              /* Are we choked? */
  37.         rhdr.opcode = NR4OPACK | NR4CHOKE ;
  38.     else
  39.         rhdr.opcode = NR4OPACK ;
  40.     rhdr.yourindex = cb->yournum ;
  41.     rhdr.yourid = cb->yourid ;
  42.     rhdr.u.ack.rxseq = cb->rxpected ;
  43.  
  44.     nr4sframe(cb->remote.node, &rhdr, NULLBUF) ;
  45. }
  46.  
  47. /* Called when one of the transmit timers has expired */
  48.  
  49. void
  50. nr4txtimeout(p)
  51. void *p ;
  52. {
  53.     struct nr4cb *cb = (struct nr4cb *)p ;
  54.     unsigned seq ;
  55.     struct nr4txbuf *t ;
  56.  
  57.     /* Sanity check */
  58.  
  59.     if (cb->state != NR4STCON)
  60.         return ;
  61.  
  62.     /* Scan through the send window looking for expired timers */
  63.     
  64.     for (seq = cb->ackxpected ;
  65.          nr4between((unsigned)cb->ackxpected, seq, (unsigned)cb->nextosend) ;
  66.          seq = (seq + 1) & NR4SEQMASK) {
  67.         
  68.         t = &cb->txbufs[seq % cb->window] ;
  69.  
  70.         if (t->tretry.state == TIMER_EXPIRE) {
  71.             t->tretry.state = TIMER_STOP ;    /* So we don't do it again */
  72.             /* This thing above fails because the timer code
  73.                itself does the reverse, changing TIMER_STOP to
  74.                TIMER_EXPIRE.  What we really want to do here
  75.                is properly restart the timer.  -- N1BEE */
  76.             /* start_timer(&(t->tretry)); */
  77.  
  78.             if (t->retries == Nr4retries) {
  79.                 cb->dreason = NR4RTIMEOUT ;
  80.                 nr4state(cb, NR4STDISC) ;
  81.             }
  82.  
  83.             t->retries++ ;
  84.             
  85.             /* We keep track of the highest retry count in the window. */
  86.             /* If packet times out and its new retry count exceeds the */
  87.             /* max, we update the max and bump the backoff level.  This */
  88.             /* expedient is to avoid bumping the backoff level for every */
  89.             /* expiration, since with more than one timer we would back */
  90.             /* off way too fast (and at a rate dependent on the window */
  91.             /* size! */
  92.  
  93.             if (t->retries > cb->txmax) {
  94.                 cb->blevel++ ;
  95.                 cb->txmax = t->retries ;    /* update the max */
  96.             }
  97.             
  98.             nr4sbuf(cb,seq) ;    /* Resend buffer */
  99.         }
  100.      }
  101.     
  102. }
  103.  
  104. /* Connect/disconnect acknowledgement timeout */
  105.  
  106. void
  107. nr4cdtimeout(p)
  108. void *p ;
  109. {
  110.     struct nr4cb *cb = (struct nr4cb *)p ;
  111.     struct nr4hdr hdr ;
  112.  
  113.     switch(cb->state) {
  114.       case NR4STCPEND:
  115.           if (cb->cdtries == Nr4retries) {    /* Have we tried long enough? */
  116.             cb->dreason = NR4RTIMEOUT ;
  117.             nr4state(cb, NR4STDISC) ;        /* Give it up */
  118.         } else {
  119.             /* Set up header */
  120.             
  121.             hdr.opcode = NR4OPCONRQ ;
  122.             hdr.u.conreq.myindex = cb->mynum ;
  123.             hdr.u.conreq.myid = cb->myid ;
  124.             hdr.u.conreq.window = Nr4window ;
  125.             memcpy(hdr.u.conreq.user,cb->local.user,AXALEN) ;
  126.             memcpy(hdr.u.conreq.node,cb->local.node,AXALEN) ;
  127.  
  128.             /* Bump tries counter and backoff level, and restart timer */
  129.             /* We use a linear or binary exponential backoff. */
  130.             
  131.             cb->cdtries++ ;
  132.             cb->blevel++ ;
  133.  
  134.             if(Nr_timertype)
  135.                 /* linear */
  136.                 set_timer(&cb->tcd,dur_timer(&cb->tcd)+cb->srtt);
  137.             else
  138.                 /* exponential */
  139.                 set_timer(&cb->tcd,dur_timer(&cb->tcd)*2);
  140.  
  141.             start_timer(&cb->tcd) ;
  142.  
  143.             /* Send connect request packet */
  144.  
  145.             nr4sframe(cb->remote.node,&hdr, NULLBUF) ;
  146.         }
  147.         break ;
  148.         
  149.       case NR4STDPEND:
  150.           if (cb->cdtries == Nr4retries) {    /* Have we tried long enough? */
  151.             cb->dreason = NR4RTIMEOUT ;
  152.             nr4state(cb, NR4STDISC) ;        /* Give it up */
  153.         } else {
  154.             /* Format header */
  155.             
  156.             hdr.opcode = NR4OPDISRQ ;
  157.             hdr.yourindex = cb->yournum ;
  158.             hdr.yourid = cb->yourid ;
  159.  
  160.             /* Bump retry count and start timer */
  161.             /* We don't really need to be fancy here, since we */
  162.             /* should have a good idea of the round trip time by now. */
  163.             
  164.             cb->cdtries++ ;
  165.             start_timer(&cb->tcd) ;
  166.  
  167.             /* Send disconnect request packet */
  168.  
  169.             nr4sframe(cb->remote.node,&hdr, NULLBUF) ;
  170.         }
  171.         break ;
  172.     }
  173. }
  174.  
  175. /* The choke timer has expired.  Unchoke and kick. */
  176.  
  177. void
  178. nr4unchoke(p)
  179. void *p ;
  180. {
  181.     struct nr4cb *cb = (struct nr4cb *)p ;
  182.  
  183.     cb->choked = 0 ;
  184.     nr4output(cb) ;
  185. }
  186.  
  187.